/**
 * 
 */
package com.ly.hotel.board;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.security.InvalidParameterException;

import com.ly.hotel.common.Constants;
import com.ly.hotel.common.MyApplication;
import com.ly.hotel.util.CrcUtil;
import com.ly.hotel.util.LyStringUtil;

import android.content.Intent;
import android.os.Build;
import android.util.Log;
import android_serialport_api.SerialPort;

/**
 * @author jouson 2014-7-17 
 * 串口类型的ID卡 长度是10位数字
 * 
 * 串口类型的IC_ID卡，长度9 ，02 开头，1位数据长度，5位序列号（后3位才是真正的ID），1位校验和(crc8,(1位数据长度，5位序列号))，03结尾,返回50或没有返回，为错误。需要重新发数据。收到55后，等待卡移开。
 * 
 * 泰格M1卡，长度15，格式M1-0123456789\r\n
 * 
 * HSJ多合一读卡器  14位长度 开头为39  10位 10进制卡号 帧尾 0D 0A 
 * 卡片类型  31  ID卡   32  T57卡   33  Mifare卡
 */
public abstract class SerialPortHandler2 extends SerialPortHandler {


	public SerialPortHandler2( ) {
	}

	public synchronized SerialPort getSerialPort() throws SecurityException,
			IOException, InvalidParameterException {
		if(Build.BOARD.equals(Constants.BOARD_TYPE_ADA628_NAME)){
			return null;
		}else{
			
			if (mSerialPort == null) {
				int bps = MyApplication.getSerialBaud();
				String path = "/dev/ttyS1";
				if(Build.BOARD.equals(Constants.BOARD_TYPE_A83T_NAME)){
					path = "/dev/ttyS2";
				}
				if(Build.BOARD.equals(Constants.BOARD_TYPE_6A648_NAME)){
					bps = 115200;
				}
				File f = new File(path);
				if(f.exists()){
					Log.i("serial", "初始化串口" + path +"，波特率=" + bps);
					mSerialPort = new SerialPort(new File(path), bps, 0);
				}else{
					Log.i("serial", "无法找到设备描述符" + path);
				}
			}
			return mSerialPort;
		}
	}
	/*位反转*/
	public int fBit(int c){
		/*不需要反转了。但是需要与一下0x000000ff，返回值才会正确*/
        /*c = (c & 0xaa) >> 1 | (c & 0x55) << 1;
        c = (c & 0xcc) >> 2 | (c & 0x33) << 2;
        c = (c & 0xf0) >> 4 | (c & 0x0f) << 4;*/

        return c&0x000000ff;
	}

	public int bBit(int c){
		/*不需要反转了。但是需要与一下0x000000ff，返回值才会正确*/
        c = (c & 0xaa) >> 1 | (c & 0x55) << 1;
        c = (c & 0xcc) >> 2 | (c & 0x33) << 2;
        c = (c & 0xf0) >> 4 | (c & 0x0f) << 4;

        return c&0x000000ff;
	}
	
	protected void onDataReceived(final byte[] buffer, final int inSize,
			OutputStream out) {
		int size = inSize;
		Log.i("serial","串口2接收到数据，时间戳"+System.currentTimeMillis());
		if(System.currentTimeMillis() - uartdataInLastTime > 100){
			//上次是完整的数据，并且距离上次的时间小于100ms，就把上一次的数据和这一次的数据合并
			uartdataBufLast = "";
		}
		size += uartdataBufLast.length();
		String s = uartdataBufLast + new String(buffer, 0, inSize);
	
//		System.out.printf("接受串口数据2,数据长度%d\r\n",size);
		Log.i("serial","接受串口数据2,数据长度"+inSize);
		// if (text != null) {
		String ss = "";
		for(int i = 0;i<inSize;i++){
//			System.out.printf("0x%x ", buffer[i]);
			ss += "0x" + Integer.toHexString(buffer[i]) + " ";
		}
		Log.i("serial","数据->> "+ss);
		
		Log.i("serial","完整数据->> "+s + "完整数据长度->>" + size);
		/*只有两次输入的数据大于1秒，才上报，否则容易误触发*/
		if(System.currentTimeMillis() - dataInLastTime > 1000)
		{
			if(s.startsWith("sled,on")){
				Log.i("serial", "sled,on");
				MyApplication.getContext().sendBroadcast(new Intent(Constants.Broadcast.CALL_MENU).putExtra("flag", Constants.CALL_REQUEST));
			}else if(s.startsWith("sled,off")){
				Log.i("serial", "sled,off");
				MyApplication.getContext().sendBroadcast(new Intent(Constants.Broadcast.CALL_MENU).putExtra("flag", Constants.CALL_REQUEST));
			}else if ((size == Constants.SERIALPORT_IDCARD_HAND_NO_LEN || size == Constants.SERIALPORT_IDCARD_HAND_NO_LEN_12) && !s.startsWith("9")) {
				String handNo = s.replace("\n", "").replace("\r", "");
				if (!handNo.trim().equals("")) {
					
					char[] num = handNo.toCharArray();
					for(char aa : num){
						if(aa-'0' < 0 || aa-'0' > 9){
							Log.i("serial","有非法字符..,0x" + Integer.toHexString(aa));
							return;	
						}
					}
					onInputComplete(handNo);
					Log.i("serial","SerialPortHabder2->send onInputComplete:"+handNo);
				}
			}else if(size == Constants.SERIALPORT_IC_ID_CARD_HAND_NO_LEN && !s.startsWith("9")) {
				byte crc = CrcUtil.calcCrc8(new byte[] {buffer[1],buffer[2],buffer[3],buffer[4],buffer[5],buffer[6]});

				System.out.printf("0x%x 0x%x 0x%x  0x%x\r\n", buffer[4],buffer[5],buffer[6],crc);
				if(crc != buffer[7]){
					Log.i("serial","CRC校验出错.");
					return;	
				}
				long tmp = 0x0000000000000000L;
				String b;
				String a;
//				tmp = (long)buffer[2]<<32 | (long)buffer[3]<<24 | (long)buffer[4]<<16 | (long)buffer[5]<<8 | (long)buffer[6];
				if(buffer[3] != 0 && buffer[6] == 0){
					//IC卡
					Log.i("serial","这是一张IC卡\r\n");
					tmp = (long)fBit(buffer[2])<<24 | (long)fBit(buffer[3])<<16 | (long)fBit(buffer[4])<<8  | (long)fBit(buffer[5]);
					tmp = tmp & 0x00000000FFFFFFFFL;
					
					b = Long.toString(tmp);
					a = "";
					
				}else{
					//ID卡
					Log.i("serial","这是一张ID卡\r\n");
					tmp = (long)fBit(buffer[4])<<16 | (long)fBit(buffer[5])<<8 | (long)fBit(buffer[6]);
					tmp = tmp & 0x0000000000FFFFFFL;
					
					b = Long.toString(tmp);
					a = "";
					for(int i=0;i<10-b.length();i++)
						a += "0";
					
				}
				//tmp = (long)(buffer[4])<<16 | (long)(buffer[5])<<8 | (long)(buffer[6]);

				/*应答收到了数据包，这样就不会重复发送过来了*/
				/*byte[] bi = {0x55};
				try {
					out.write(bi);
				} catch (IOException e) {
					e.printStackTrace();
				}*/ 

				a += b;	
				
				System.out.println("SerialPortHabder2->send onInputComplete:"+a);
				char[] num = a.toCharArray();
				for(char aa : num){
					if(aa-'0' < 0 || aa-'0' > 9){
						Log.i("serial","有非法字符..");
						return;	
					}
				}
				onInputComplete(a); 
			}else if (s.contains("M1-") && (size == Constants.SERIALPORT_M1_CARD_HAND_NO_LEN1 || size == Constants.SERIALPORT_M1_CARD_HAND_NO_LEN2)) {
				String handNo = s.replace("\n", "").replace("\r", "").replace("M1-", "");
				if (!handNo.trim().equals("")) {
					//接收到的是M1-31A3F79DF8，保留31A3F79D，并按照16进制倒序，即9DF7A331,变成10进制就是2650252081
					byte[] num = LyStringUtil.hexStringToBytes(handNo);
//					long no = ((long)(num[3]<<24) | (long)(num[2]<<16) | (long)(num[1]<<8) | (long)(num[0])) & 0x00000000FFFFFFFF;
					byte[] value = {num[3],num[2],num[1],num[0]};

					long i = getLong(value,0);
					onInputComplete(String.valueOf(i));
					Log.i("serial","SerialPortHabder2->send onInputComplete:"+i);
				}
			}else if (s.getBytes()[0] == 0x39 && size == Constants.SERIALPORT_HSJ_CARD_READER_LEN) {
				Byte b = s.getBytes()[1];
				//帧头 39  表示HSJ
				//卡片类型  31  ID卡   32  T57卡   33  Mifare卡
				Log.i("serial","检测到HSJ读卡器:");
				if(b == 0x31)
					Log.i("serial","这是ID卡");
				else if(b == 0x32)
					Log.i("serial","这是T57卡");
				else if(b == 0x33)
					Log.i("serial","这是Mifare或者IC卡");
				
//				String handNo = new String(buffer, 2, 10);
				String handNo = s.substring(2);
				if (!handNo.trim().equals("")) {
					
	/*				long i = getLong(value,0);*/
					onInputComplete(handNo);
					Log.i("serial","SerialPortHabder2->send onInputComplete:"+handNo);
				}
			}else if (size == Constants.SERIALPORT_TAI_GE_CARD_HAND_NO_LEN) {
				byte[] buf  = s.getBytes();
				if(buf[0] == 0x0d && buf[1] == '#' && buf[18] == '.'  && buf[19] == 0x0a){
					//帧头 0x0D 和 # 尾部是 . 和0x0a
					//数据是16进制，一个16个字符组成的8个16进制
					Log.i("serial","泰格接触式读卡器:");
					
					String handNo = new String(buf, 2, 16);
					
					if (!handNo.trim().equals("")) {
				
						onInputComplete(handNo);
						Log.i("serial","SerialPortHabder2->send onInputComplete:"+handNo);
					}
				} 
			}else if (size == Constants.SERIALPORT_HJ_CARD_HAND_NO_LEN) {
				byte[] buf  = s.getBytes();
				if(buf[0] == 'E' && buf[1] == 'M' && buf[15] == 0x0d  && buf[16] == 0x0a){
					//帧头 0x0D 和 # 尾部是 . 和0x0a
					//数据是16进制，一个16个字符组成的8个16进制
					Log.i("serial","航嘉EM4305读卡器:");
					
					String handNo = new String(buf, 7, 8);
					
					if (!handNo.trim().equals("")) {
				
						onInputComplete(handNo);
						Log.i("serial","SerialPortHabder2->send onInputComplete:"+handNo);
					}
				} 
			}else{
				uartdataBufLast = s;
				//保存这次的接收的时间戳,方便判断分两次传上数据的情况
				uartdataInLastTime = System.currentTimeMillis();
				Log.d("serial","长度不达标..时间戳->>" + uartdataInLastTime);
				return;	
			}
		}
		else
		{
			Log.i("serial","手牌没有松开，数据无效");
		}
		
		dataInLastTime = System.currentTimeMillis();
	}
	
	private static long getLong(byte buf[], int index){
		int firstByte = (0x000000FF & ((int) buf[index + 3]));
		int secondByte = (0x000000FF & ((int) buf[index + 2]));
		int thirdByte = (0x000000FF & ((int) buf[index + 1]));
		int fourthByte = (0x000000FF & ((int) buf[index]));

		long unsignedLong = ((long) (firstByte | secondByte << 8 | thirdByte << 16 | fourthByte << 24)) & 0xFFFFFFFFL;

		return unsignedLong;
	}
	
	public boolean deviceExist(){
		File f = new File("/dev/ttyS1");
		if(f.exists()){
			return true;
		}else{
			return false;
		}
	}
}
